import { defineComponent, reactive, toRefs, computed, watch, h } from "vue"
import { inject } from "vue"

import BodyCheckboxContent from "./body-checkbox-content"
import BodyRadioContent from "./body-radio-content"
import ExpandTrIcon from "./expand-tr-icon"
import { getRowKeysByRangeRowKeys } from "../util"
import { COMPS_NAME, COLUMN_TYPES, EXPAND_TRIGGER_TYPES, EMIT_EVENTS, COMPS_CUSTOM_ATTRS } from "../util/constant"
import emitter from "amtf/utils/emitter"
import { useEmitter } from "amtf/hooks"

import { use样式 } from "amtf/hooks"
import { isNumber, isEmptyValue, getValByUnit, 拼组件名, isFunction, isBoolean, getRandomId } from "amtf/utils"
const 主名 = "table-body-td"
const 组件名 = 拼组件名(主名)

export default defineComponent({
    name: 组件名,
    props: {
        rowData: {
            type: Object,
            required: true,
        },
        column: {
            type: Object,
            required: true,
        },
        columnCollection: {
            type: Object,
            required: true,
        },
        rowIndex: {
            type: Number,
            required: true,
        },
        colgroups: {
            type: Array,
            required: true,
        },
        rowKeyFieldName: {
            type: String,
            default: null,
        },
        allRowKeys: {
            type: Array,
            required: true,
        },
        // expand row option
        expandOption: {
            type: Object,
            default: () => null,
        },
        // is expand row
        isExpandRow: {
            type: Boolean,
            required: true,
        },
        // expanded row keys
        expandedRowkeys: {
            type: Array,
            default: () => [],
        },
        // checkbox option
        checkboxOption: {
            type: Object,
            default: () => null,
        },
        internalCheckboxSelectedRowKeys: {
            type: Array,
            default: () => null,
        },
        // radio option
        radioOption: {
            type: Object,
            default: () => null,
        },
        internalRadioSelectedRowKey: {
            type: [String, Number],
            default: null,
        },
        // cell style option
        cellStyleOption: {
            type: Object,
            default: () => null,
        },
        // event custom option
        eventCustomOption: {
            type: Object,
            default: () => null,
        },
        // cell selection data
        cellSelectionData: {
            type: Object,
            default: () => null,
        },
        // cell selection range data
        cellSelectionRangeData: {
            type: Object,
            default: () => null,
        },
        bodyIndicatorRowKeys: {
            type: Object,
            default: () => null,
        },
        // cell span option
        cellSpanOption: {
            type: Object,
            default: () => null,
        },
        // edit opttion
        editOption: {
            type: Object,
            default: () => null,
        },
    },
    setup(props) {
        // console.log(`props.columnCollection 👉`, props.columnCollection)
        const { dispatch } = useEmitter(inject("表格id"))
        const { 拼样式名_table直属 } = use样式(主名)

        const state = reactive({
            rawCellValue: "",
        })

        const currentColumnCollectionItem = computed(() => {
            const { columnCollection, column } = props
            return columnCollection.value.find(x => x.colKey === column.key)
        })

        const currentRowKey = computed(() => {
            const { rowData, rowKeyFieldName } = props
            return rowData[rowKeyFieldName]
        })

        watch(
            () => props.rowData,
            rowData => {
                const column = props.column
                if (column) {
                    state.rawCellValue = rowData[column.field]
                }
            },
            { deep: true, immediate: true }
        )

        function bodyTdStyle() {
            let result = {}
            if (currentColumnCollectionItem.value) {
                result = Object.assign(result, currentColumnCollectionItem.value.style)
            }
            // console.log(`result 👉`, result)
            return result
        }

        function bodyTdClass() {
            const { fixed, operationColumn } = props.column
            let result = {
                [拼样式名_table直属("body-td")]: true,
            }
            const {
                cellStyleOption,
                rowData,
                column,
                rowIndex,
                allRowKeys,
                cellSelectionData,
                cellSelectionRangeData,
                bodyIndicatorRowKeys,
                currentRowKey,
            } = props
            // column fixed
            // console.log(`fixed 👉`, fixed)
            if (fixed) {
                result[拼样式名_table直属("fixed-left")] = fixed === "left"
                result[拼样式名_table直属("fixed-right")] = fixed === "right"
            }
            // operation column
            if (operationColumn) {
                result[拼样式名_table直属("operation-col")] = true
            }
            // cell style option
            if (cellStyleOption && typeof cellStyleOption.bodyCellClass === "function") {
                const customClass = cellStyleOption.bodyCellClass({
                    row: rowData,
                    column,
                    rowIndex,
                })
                if (customClass) {
                    result[customClass] = true
                }
            }
            if (cellSelectionData) {
                const { rowKey, colKey } = cellSelectionData.currentCell
                if (!isEmptyValue(rowKey) && !isEmptyValue(colKey)) {
                    if (currentRowKey === rowKey) {
                        // cell selection
                        if (column["key"] === colKey) {
                            result[拼样式名_table直属("cell-selection")] = true
                        }
                    }
                    if (operationColumn) {
                        const { topRowKey, bottomRowKey } = cellSelectionRangeData
                        const { startRowKeyIndex } = bodyIndicatorRowKeys
                        const isIndicatorActive = startRowKeyIndex > -1
                        let indicatorRowKeys = []
                        if (topRowKey === bottomRowKey) {
                            indicatorRowKeys = [topRowKey]
                        } else {
                            indicatorRowKeys = getRowKeysByRangeRowKeys({
                                topRowKey,
                                bottomRowKey,
                                allRowKeys,
                            })
                        }
                        // cell indicator (operation column)
                        if (indicatorRowKeys.indexOf(currentRowKey) > -1) {
                            if (isIndicatorActive) {
                                result[拼样式名_table直属("cell-indicator-active")] = true
                            } else {
                                result[拼样式名_table直属("cell-indicator")] = true
                            }
                        }
                    }
                }
            }
            if (currentColumnCollectionItem.value) {
                result = Object.assign(result, currentColumnCollectionItem.value.class)
            }
            // console.log(`result 👉`, result)
            return result
        }

        function getEllipsisContentStyle() {
            let result = {}
            const { ellipsis } = props.column
            if (ellipsis) {
                const { lineClamp } = ellipsis
                let _lineClamp = isNumber(lineClamp) ? lineClamp : 1
                result["-webkit-line-clamp"] = _lineClamp
            }
            return result
        }

        function getRenderContent(h) {
            const { column, rowData, rowIndex } = props
            // console.log(`column 👉`, column)
            let content = null
            // console.log(`column.renderBodyCell 👉`, column.renderBodyCell)
            // has render function
            if (typeof column.renderBodyCell === "function") {
                const renderResult = column.renderBodyCell(
                    {
                        row: rowData,
                        column,
                        rowIndex,
                    },
                    h
                )
                content = renderResult
            } else {
                content = state.rawCellValue
            }
            // ellipisis
            if (column.ellipsis) {
                const { showTitle } = column.ellipsis
                // default true
                const isShowTitle = isBoolean(showTitle) ? showTitle : true
                content = (
                    <span
                        title={isShowTitle ? content : ""}
                        style={getEllipsisContentStyle()}
                        class={拼样式名_table直属("body-td-span-ellipsis")}>
                        {content}
                    </span>
                )
            }
            // console.log(`content 👉`, content)
            return content
        }

        function getCheckboxContent() {
            if (props.column.type === COLUMN_TYPES.CHECKBOX) {
                // checkbox content props
                const checkboxProps = {
                    column: props.column,
                    checkboxOption: props.checkboxOption,
                    rowKey: props.rowData[props.rowKeyFieldName],
                    internalCheckboxSelectedRowKeys: props.internalCheckboxSelectedRowKeys,
                }
                return <BodyCheckboxContent {...checkboxProps} />
            }
            return null
        }

        function getRadioContent() {
            if (props.column.type === COLUMN_TYPES.RADIO) {
                const radioProps = {
                    column: props.column,
                    radioOption: props.radioOption,
                    rowKey: props.rowData[props.rowKeyFieldName],
                    internalRadioSelectedRowKey: props.internalRadioSelectedRowKey,
                }
                return <BodyRadioContent {...radioProps} />
            }
            return null
        }

        function getCellSpan() {
            const { cellSpanOption, rowData, column, rowIndex } = props
            let rowspan = 1
            let colspan = 1
            if (cellSpanOption) {
                const { bodyCellSpan } = cellSpanOption
                if (typeof bodyCellSpan === "function") {
                    const result = bodyCellSpan({
                        row: rowData,
                        column,
                        rowIndex,
                    })
                    if (typeof result === "object") {
                        rowspan = result.rowspan
                        colspan = result.colspan
                    }
                }
            }
            return { rowspan, colspan }
        }

        function cellClick(e, fn) {
            fn && fn(e)
            const { column, expandOption, rowData } = props
            dispatch(EMIT_EVENTS.BODY_CELL_CLICK, {
                event: e,
                rowData,
                column,
            })
            if (column.type !== COLUMN_TYPES.EXPAND) {
                return false
            }
            if (expandOption) {
                const eventTargetName = e.target.nodeName
                const trigger = expandOption.trigger
                // expand row by click icon
                if (!trigger || trigger === EXPAND_TRIGGER_TYPES.ICON) {
                    if (eventTargetName !== "TD") {
                        e.stopPropagation()
                        dispatch(EMIT_EVENTS.EXPAND_ROW_CHANGE)
                    }
                }
                // expand row by click cell(td)
                else if (trigger === EXPAND_TRIGGER_TYPES.CELL) {
                    e.stopPropagation()
                    dispatch(EMIT_EVENTS.EXPAND_ROW_CHANGE)
                }
            }
        }

        function cellDblclick(e, fn) {
            fn && fn(e)
            const { column, rowData } = props
            dispatch(EMIT_EVENTS.BODY_CELL_DOUBLE_CLICK, {
                event: e,
                rowData,
                column,
            })
        }

        function cellContextmenu(e, fn) {
            fn && fn(e)
            const { column, rowData } = props
            dispatch(EMIT_EVENTS.BODY_CELL_CONTEXTMENU, {
                event: e,
                rowData,
                column,
            })
        }

        function cellMouseenter(e, fn) {
            fn && fn(e)
        }

        function cellMouseleave(e, fn) {
            fn && fn(e)
        }

        function cellMousemove(e, fn) {
            fn && fn(e)
            const { column, rowData } = props
            dispatch(EMIT_EVENTS.BODY_CELL_MOUSEMOVE, {
                event: e,
                rowData,
                column,
            })
        }

        function cellMouseover(e, fn) {
            fn && fn(e)
            const { column, rowData } = props
            dispatch(EMIT_EVENTS.BODY_CELL_MOUSEOVER, {
                event: e,
                rowData,
                column,
            })
        }

        function cellMousedown(e, fn) {
            fn && fn(e)
            const { column, rowData } = props
            // console.log(`cellMousedown ing👇`)
            dispatch(EMIT_EVENTS.BODY_CELL_MOUSEDOWN, {
                event: e,
                rowData,
                column,
            })
        }

        function cellMouseup(e, fn) {
            fn && fn(e)
            const { column, rowData } = props
            dispatch(EMIT_EVENTS.BODY_CELL_MOUSEUP, {
                event: e,
                rowData,
                column,
            })
        }

        const { rowspan, colspan } = getCellSpan()
        if (!rowspan || !colspan) {
            return null
        }

        // custom on cell event
        let customEvents = {}
        if (props.eventCustomOption) {
            const { bodyCellEvents } = props.eventCustomOption
            customEvents = bodyCellEvents ? bodyCellEvents({ row: props.rowData, column, rowIndex }) : {}
        }

        const { click, dblclick, contextmenu, mouseenter, mouseleave, mousemove, mouseover, mousedown, mouseup } =
            customEvents

        const events = {
            onClick: e => cellClick(e, click),
            onDblclick: e => cellDblclick(e, dblclick),
            onContextmenu: e => cellContextmenu(e, contextmenu),
            onMouseenter: e => cellMouseenter(e, mouseenter),
            onMouseleave: e => cellMouseleave(e, mouseleave),
            onMousemove: e => cellMousemove(e, mousemove),
            onMouseover: e => cellMouseover(e, mouseover),
            onMousedown: e => cellMousedown(e, mousedown),
            onMouseup: e => cellMouseup(e, mouseup),
        }

        const expandIconProps = {
            rowData: props.rowData,
            column: props.column,
            expandOption: props.expandOption,
            expandedRowkeys: props.expandedRowkeys,
            rowKeyFieldName: props.rowKeyFieldName,
            cellClick,
        }

        return () => (
            <td
                class={bodyTdClass()}
                style={bodyTdStyle()}
                {...{
                    rowspan,
                    colspan,
                    [COMPS_CUSTOM_ATTRS.BODY_COLUMN_KEY]: props.column.key,
                }}
                {...events}>
                {/* expadn tr icon */}
                {props.isExpandRow && <ExpandTrIcon {...expandIconProps} />}
                {/* checkbox content */}
                {getCheckboxContent()}
                {/* radio content */}
                {getRadioContent()}
                {/* other cell content */}
                {getRenderContent(h)}
            </td>
        )
    },
})
